package com.example.java_gobang.api;

import com.example.java_gobang.game.MatchRequest;
import com.example.java_gobang.game.MatchResponse;
import com.example.java_gobang.game.Matcher;
import com.example.java_gobang.game.OnlineUserManager;
import com.example.java_gobang.model.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * @author hanzishuai
 * @date 2025/03/01 19:01
 * @Description
 */
// 通过这个类来处理匹配功能中的 websocket 请求
@Slf4j
@Component
public class MatchAPI extends TextWebSocketHandler {

    private ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private OnlineUserManager onlineUserManager;

    @Autowired
    private Matcher matcher;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        try {
            // 玩家上线，加入到 onlineUserManager 中
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if (onlineUserManager.getFromGameHall(user.getUserId()) != null
                    || onlineUserManager.getFromGameRoom(user.getUserId()) != null) {
                // 当前用户已登录！
                MatchResponse response = new MatchResponse();
                response.setOk(true);
                response.setReason("不允许多开！");
                response.setMessage("repeatConnection");
                session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
                // session.close();
                return;
            }
            onlineUserManager.enterGameHall(user.getUserId(), session);
            log.info("玩家：" + user.getUsername() + "进入游戏大厅！");
        } catch (NullPointerException e) {
            // 用户未登录
//            e.printStackTrace();
            log.error("用户未登录！");
            MatchResponse response = new MatchResponse();
            response.setOk(false);
            response.setMessage("您尚未登录，请先登录！");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }

    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 处理开始匹配请求和处理停止匹配请求
        User user = (User) session.getAttributes().get("user");
        // 接收客户端发来的数据
        String payload = message.getPayload();
        // 当前数据的载荷是一个 JSON 格式的字符串，需要转换成 Java 对象。
        MatchRequest matchRequest = objectMapper.readValue(payload, MatchRequest.class);
        MatchResponse matchResponse = new MatchResponse();
        if ("startMatch".equals(matchRequest.getMessage())) {
            // 进入匹配队列
            matcher.add(user);
            // 返回响应
            matchResponse.setOk(true);
            matchResponse.setMessage("startMatch");
        } else if ("stopMatch".equals(matchRequest.getMessage())) {
            // 退出匹配队列
            matcher.remove(user);
            matchResponse.setOk(true);
            matchResponse.setMessage("stopMatch");
        } else {
            // 非法情况
            matchResponse.setOk(false);
            matchResponse.setMessage("非法的匹配请求");
        }
        String jsonString = objectMapper.writeValueAsString(matchResponse);
        session.sendMessage(new TextMessage(jsonString));
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        try {
            // 玩家下线，从 onlineUserManager 删除
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if (tmpSession == session) {
                onlineUserManager.exitGameHall(user.getUserId());
            }

            // 如果玩家正在匹配中，此时 websocket 连接断开，这时也需要将玩家从匹配队列中移除
            matcher.remove(user);
        } catch (NullPointerException e) {
            // 用户未登录
            log.error("当前用户未登录！");
//            e.printStackTrace();
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setMessage("您尚未登录，请先登录！");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        try {
            // 玩家下线，从 onlineUserManager 删除
            User user = (User) session.getAttributes().get("user");
            WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
            if (tmpSession == session) {
                onlineUserManager.exitGameHall(user.getUserId());
            }

            // 如果玩家正在匹配中，此时 websocket 连接断开，这时也需要将玩家从匹配队列中移除
            matcher.remove(user);
        } catch (NullPointerException e) {
            // 用户未登录
            log.error("当前用户未登录！");
//            e.printStackTrace();
//            MatchResponse response = new MatchResponse();
//            response.setOk(false);
//            response.setMessage("您尚未登录，请先登录！");
//            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
        }

    }
}
